--简易锁
--KEYS[1] 锁的key
--ARGV[1] 锁的value:uuid
--ARGV[2] 锁的过期时间

--添加锁
--业务逻辑：判断该键是否存在，如果存在则返回0，如果不存在则设置锁并设置过期时间返回1
if(redis.call('exit', KEYS[1]) == 0 ) then
    redis.call('set', KEYS[1], ARGV[1]);
    redis.call('expire', KEYS[1], 30000);
    return 1;
else
    return 0;
end;

--释放锁
--业务逻辑，判断锁是否存在，如果不存在则返回0，若存在则进行判断是否是本线程，如果是则进行删除锁，否则直接返回
if(redis.call('exit', KEYS[1]) == 0) then
    return 0;
end;
if(redis.call('get', KEYS[1]) == ARGV[1]) then
    redis.call('del', KEYS[1]);
    return 1;
else
    return 0;
end;

--可重入锁：添加锁，进行锁的逻辑
--业务逻辑，使用hset进行存储键值：uuid,可重入的次数
--当redis里面没有该键时就进行存储该键，增加1，设置过期时间
if(redis.call('exit', KEYS[1]) ==0 ) then
    redis.call('hincrby',KEYS[1],ARGV[1],1);
    redis.call('pexpire',KEYS[1],ARGV[2]);
    return 1;
end;
--当redis里面有该键时，进行判断是否存在该uuid,如果存在则将可重入次数加1
if(redis.call('hexists',KEYS[1],ARGV[1]) == 1) then
    redis.call('hincrby',KEYS[1],ARGV[1],1);
    redis.call('expire',KEYS[1],ARGV[2]);
    return 1;
else
    return 0;
end;

--可重入锁：释放锁
--业务逻辑：判断该键和uuid是否存在，如果不存在则直接进行返回
if(redis.call('hexists',KEYS[1],ARGV[1]) == 0) then
    return 0;
end;
--若存在，则进行扣减1
local lockCount = redis.call('hincrby',KEYS[1],ARGV[1],-1);
--将其中还有键时就重新设置过期时间
if(lockCount > 0) then
    redis.call('pexpire',KEYS[1],ARGV[2]);
    return 1;
--否则进行删除锁
else
    redis.call('del',KEYS[1]);
    return 1;
end;

--lua脚本实现自动续期
--判断当前持有锁的线程是不是本线程，如果是则进行锁续期，如果不是则返回return
if(redis.call('hexists',KEYS[1],ARGV[1]) == 0) then
    return 0;
else
    redis.call('pexpire',KEYS[1],ARGV[2]);
    return 1;
end;